package com.dubbo.server.api;

import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dubbo.server.config.HuanXinConfig;
import com.dubbo.server.mapper.HuanXinUserMapper;
import com.dubbo.server.service.RequestService;
import com.dubbo.server.service.TokenService;
import com.tanhua.common.enums.HuanXinMessageType;
import com.tanhua.common.pojo.HuanXinUser;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;
import java.util.Date;

@Service(timeout = 60000)
@Slf4j
public class HuanXinApiImpl implements HuanXinApi {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private HuanXinConfig huanXinConfig;

    @Autowired
    private RequestService requestService;

    @Autowired
    private HuanXinUserMapper huanXinUserMapper;

    @Override
    public String getToken() {
        return this.tokenService.getToken();
    }


    /**
     * 注册环信用户
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public Boolean register(Long userId) {
        // 这个地址要能够在环信的api文档上找到
        String targetUrl = this.huanXinConfig.getUrl()
                + this.huanXinConfig.getOrgName() + "/" +
                this.huanXinConfig.getAppName() + "/users";

        // 按照文档上的要求去拼接参数
        // 用户名和密码我们存到哪里 ? 需不需要存储   APP需要登录连接环信的时候要使用用户名和密码
        // 看环信有没有提供一个查询密码的功能
        // 如果你的密码是固定的  每个人都是一样的  APP 中使用环信通信的账号密码
        // 可以给每个人设置一个不同的密码  但是要有一定的规则  MD5(id+手机号+固定的盐/手机号码的前三后四组合一下)  告诉APP
        // 如果我们把用户的环信账号和密码存储起来的话 也可以保存到原来的user表中
        // 环信的账号和密码是给 APP用的　　你只能想办法让APP能够知道每个用户的环信账号密码即可
        HuanXinUser huanXinUser = new HuanXinUser();
        // 环信的用户名
        huanXinUser.setUsername("HX_" + userId);  // 用户名
        // 环信的密码  随机的UUID
        huanXinUser.setPassword(IdUtil.simpleUUID()); //随机生成的密码
        // 给环信发送注册用户的请求                                                          [{username:"HX_1",password:"xxxx"}]
        HttpResponse response = this.requestService.execute(targetUrl, JSONUtil.toJsonStr(Arrays.asList(huanXinUser)), Method.POST);
        // 如果环信新增用户成功后  把这个用户的环信账号和密码存储到MYSQL
        if (response.isOk()) {
            //将环信的账号信息保存到数据库
            huanXinUser.setUserId(userId);
            huanXinUser.setCreated(new Date());
            huanXinUser.setUpdated(huanXinUser.getCreated());
            // 把环信的账号密码存储到MYSQL
            this.huanXinUserMapper.insert(huanXinUser);
            return true;
        }
        return false;
    }


    /**
     * 根据环信的ID去MYSQL查询环信的用户信息
     * userId 是token中携带过来的
     *
     * @param userId
     * @return
     */
    @Override
    public HuanXinUser queryHuanXinUser(Long userId) {
        QueryWrapper<HuanXinUser> wrapper = new QueryWrapper<>();
//        userId=1   通过这个查
        wrapper.eq("user_id", userId);
        return this.huanXinUserMapper.selectOne(wrapper);
    }


    /**
     * 根据用户名去查询环信的用户信息
     *
     * @param userName
     * @return
     */
    @Override
    public HuanXinUser queryUserByUserName(String userName) {
        QueryWrapper<HuanXinUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", userName);
        return this.huanXinUserMapper.selectOne(wrapper);
    }


    /**
     * 绑定环信的好友关系
     *
     * @param userId   自己的id
     * @param friendId 好友的id
     * @return
     */
    @Override
    public Boolean addUserFriend(Long userId, Long friendId) {
        // 地址从环信的文档中查找
        String targetUrl = this.huanXinConfig.getUrl()
                + this.huanXinConfig.getOrgName() + "/"
                + this.huanXinConfig.getAppName() + "/users/HX_" +
                userId + "/contacts/users/HX_" + friendId;
        try {
            // 404 -> 对方未在环信注册
            // 如果是返回401  重试4次  一共5次　　　A　＝＝　B　　
            return this.requestService.execute(targetUrl, null, Method.POST).isOk();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 添加失败
        return false;
    }


    /**
     * 解除好友的关系
     *
     * @param userId   自己的id
     * @param friendId 好友的id
     * @return
     */
    @Override
    public Boolean removeUserFriend(Long userId, Long friendId) {
        String targetUrl = this.huanXinConfig.getUrl()
                + this.huanXinConfig.getOrgName() + "/"
                + this.huanXinConfig.getAppName() + "/users/HX_" +
                userId + "/contacts/users/HX_" + friendId;
        try {
            // 404 -> 对方未在环信注册
            return this.requestService.execute(targetUrl, null, Method.DELETE).isOk();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 添加失败
        return false;
    }

    /**
     * 以管理员身份发送消息
     *
     * @return
     */
    @Override
    public Boolean sendMsgFromAdmin(String targetUserName, HuanXinMessageType huanXinMessageType, String msg) {
        String targetUrl = this.huanXinConfig.getUrl()
                + this.huanXinConfig.getOrgName() + "/"
                + this.huanXinConfig.getAppName() + "/messages";

        try {
            //{"target_type": "users","target": ["user2","user3"],"msg": {"type": "txt","msg": "testmessage"},"from": "user1"}
            String body = JSONUtil.createObj()
                    .set("target_type", "users")
                    .set("target", JSONUtil.createArray().set(targetUserName))
                    .set("msg", JSONUtil.createObj()
                            .set("type", huanXinMessageType.getType())
                            .set("msg", msg)).toString();
            //表示消息发送者;无此字段Server会默认设置为“from”:“admin”，有from字段但值为空串(“”)时请求失败
//                .set("from", "")

            return this.requestService.execute(targetUrl, body, Method.POST).isOk();
        } catch (Exception e) {
            log.error("发送消息失败~ targetUserName = " + targetUserName + ", type = " + huanXinMessageType.getType() + ", msg = " + msg, e);
        }
        return false;
    }
}
